/*最小生成树
 * Kruskal算法
 * 先排序，看能不能加
 * 判断：两点是否联通，并查集维护
 * O(mlogm)
 */
const int N=1050;
const int M=10050;
struct Edge
{
    int a,b,c;//ab之间有长c的边
}edge[M];
int fa[N];
int n,m;
bool cmp(Edge x,Edge y)
{
    return x.c<y.c;
}
int find(int x)
{
    return x==fa[x]?fa[x]:fa[x]=find(x);
}
int main()
{
    int i,j;
    scanf("%d%d",&n,&m);
    for(i=1;i<=m;++i)
        scanf("%d%d%d",&edge[i].a,&edge[i].b,&edge[i].c);
    sort(edge+1,edge+m+1,cmp);
    for(int i=1;i<=n;++i)
        fa[i]=i;
    for(int i=1;i<=m;++i)
    {
        int a=edge[i].a;
        int b=edge[i].b;
        a=find(a),b=find(b);
        if(a!=b)
            ans+=edge[i].c,fa[a]=b;//可以在此处记录
    }
    printf("%d\n",ans);
}
/*Prim算法
 * O(n*m)
 */
const int N=1050;
const int M=10050;
struct Edge
{
    int a,b,c;//ab之间有长c的边
}edge[M];
int n,m;
bool black[N];
int main()
{
    int i,j,k;
    scanf("%d%d",&n,&m);
    for(i=1;i<=m;++i)
        scanf("%d%d%d",&edge[i].a,&edge[i].b,&edge[i].c);
    black[1]=1;
    for(k=1;k<=n-1;++k)
    {
        int mind=1,minz=MAX_INT;//最小边编号与值
        for(i=2;i<=m;++i)
            if(black[edge[i].a]!=black[edge[i].b]&&edge[i].c<minz)
                //找最小时可以用堆优化至nlogm
                mind=i,minz=edge[i].c;
    ans+=minz;
    black[edge[mind].a]=1;
    black[edge[mind].b]=1
    }

    printf("%d\n",ans);
}
